﻿''' <summary>
''' Предоставляет методы расширения для отображения HTML-элементов, образующих список для постраничного просмотра.
''' </summary>
''' <remarks></remarks>
Public Module PaginationHtmlHelper
    Private _AbsolutePath As String
    Private _PageIndex As Integer
    Private _PageCount As Integer
    Private _StartPageIndex As Integer

    ''' <summary>
    ''' Отображает немаркированный список постраничной навигации.
    ''' </summary>
    ''' <param name="helper">Экземпляр вспомогательного метода HTML, который расширяется данным методом.</param>
    ''' <param name="pageIndex">Индекс страницы.</param>
    ''' <param name="pageCount">Количество страниц.</param>
    ''' <param name="htmlAttributes">Объект, который содержит HTML-аттрибуты для элемента.</param>
    ''' <returns>Объект <see cref="MvcHtmlString" />, содержащий HTML-разметку элементов постраничной новигации.</returns>
    ''' <remarks>
    ''' Метод формирует HTML-разметку в соответствии с образцом Twitter Bootstrap. Немаркированный список <c>UL</c> помещен в контейнер элемента <c>NAV</c>, которому можно назначить CSS-класс.
    ''' </remarks>
    <Extension()>
    Public Function Pagination(helper As HtmlHelper, pageIndex As Integer, pageCount As Integer, htmlAttributes As Object) As MvcHtmlString
        If pageCount <= 1 Then Return MvcHtmlString.Empty

        _AbsolutePath = helper.ViewContext.HttpContext.Request.Url.AbsolutePath
        _PageIndex = pageIndex
        _PageCount = pageCount

        Dim nav As New TagBuilder("nav")

        With nav
            .MergeAttributes(New RouteValueDictionary(htmlAttributes))
            .InnerHtml = BuildUl()
        End With

        Return MvcHtmlString.Create(nav.ToString(TagRenderMode.Normal))
    End Function

    Private Function BuildUl() As String
        Dim ul As New TagBuilder("ul")

        With ul
            'Ссылка на предыдущую страницу.
            .InnerHtml += BuildLi(_PageIndex - 1, "‹", Not (_PageIndex > 0))

            'Ссылки на страницы.
            Dim limit = 10
            If _PageCount < limit Then limit = _PageCount

            Dim mid = CInt(Math.Floor(CDbl(limit) / 2))

            If _PageIndex > (_StartPageIndex + mid) And (_StartPageIndex + limit) < _PageCount Then
                _StartPageIndex += 1
            ElseIf _PageIndex < (_StartPageIndex + mid) And _StartPageIndex > 0 Then
                _StartPageIndex -= 1
            End If

            For i = _StartPageIndex To (_StartPageIndex + limit) - 1
                .InnerHtml += BuildLi(i, (i + 1).ToString(), False)
            Next

            'Ссылка на следующую страницу.
            .InnerHtml += BuildLi(_PageIndex + 1, "›", Not (_PageIndex < (_PageCount - 1)))
        End With

        Return ul.ToString(TagRenderMode.Normal)
    End Function

    Private Function BuildLi(currentPageIndex As Integer, text As String, disabled As Boolean) As String
        Dim li As New TagBuilder("li")
        Dim href As String = String.Empty

        With li
            If disabled Then
                .AddCssClass("disabled")
            ElseIf currentPageIndex = _PageIndex Then
                .AddCssClass("active")
            ElseIf currentPageIndex <= 0 Then
                href = _AbsolutePath
            Else
                href = String.Format("{0}?pageIndex={1}", _AbsolutePath, currentPageIndex)
            End If

            .InnerHtml = BuildA(href, text)
        End With

        Return li.ToString(TagRenderMode.Normal)
    End Function

    Private Function BuildA(href As String, text As String) As String
        Dim a As New TagBuilder("a")

        With a
            If Not String.IsNullOrEmpty(href) Then .Attributes.Add("href", href)
            .InnerHtml = text
        End With

        Return a.ToString(TagRenderMode.Normal)
    End Function


End Module
